import paho.mqtt.client as mqtt
import time
import threading

# ===== 配置参数 =====
BROKER = "localhost"  # MQTT代理地址（本地）
PORT = 1883           # 默认端口
TOPIC = "home/sensor" # 主题
QOS = 1               # 服务质量等级 (0/1/2)
INTERVAL = 3          # 发布间隔(秒)

# ===== MQTT订阅者 =====
class Subscriber:
    def __init__(self):
        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        
    def on_connect(self, client, userdata, flags, rc):
        print(f"订阅者已连接: {'成功' if rc == 0 else '失败'} (代码: {rc})")
        client.subscribe(TOPIC, qos=QOS)
        
    def on_message(self, client, userdata, msg):
        print(f"\\n收到消息: [{msg.topic}]")
        print(f"内容: {msg.payload.decode()}")
        print(f"QOS: {msg.qos}, 保留: {msg.retain}")
        
    def start(self):
        self.client.connect(BROKER, PORT, 60)
        self.client.loop_start()

# ===== MQTT发布者 =====
class Publisher:
    def __init__(self):
        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        
    def on_connect(self, client, userdata, flags, rc):
        print(f"发布者已连接: {'成功' if rc == 0 else '失败'} (代码: {rc})")
        
    def publish(self, message):
        result = self.client.publish(TOPIC, message, qos=QOS)
        status = result[0]
        if status == 0:
            print(f"消息已发送: {message}")
        else:
            print(f"消息发送失败 (状态: {status})")
    
    def start(self):
        self.client.connect(BROKER, PORT, 60)
        self.client.loop_start()
        return self

# ===== 主程序 =====
if __name__ == "__main__":
    # 启动订阅者
    sub = Subscriber()
    sub.start()
    
    # 启动发布者
    pub = Publisher().start()
    
    try:
        counter = 0
        print("\\nMQTT本地客户端运行中 (Ctrl+C退出)...")
        print("="*50)
        
        while True:
            # 每秒检查一次
            time.sleep(1)
            counter += 1
            
            # 定时发布消息
            if counter % INTERVAL == 0:
                message = f"传感器数据: {time.ctime()} | 计数: {counter//INTERVAL}"
                pub.publish(message)
                
    except KeyboardInterrupt:
        print("\\n程序已终止")
